// ES6之前，对象的属性名(key)
// const obj={
//     name : "why",
//     friend:{name:"kobe"},
//     "age":18
// }

// console.log(Object.keys(obj))
// obj['name'] = 'james'
// console.log(obj)

// Symbol是ES6新增的一个基本数据类型,翻译为符号
// 为什么需要Symbol呢？
// 在ES6之前，对象的属性名都是字符串形式，那么很容易造成属性名的冲突
// 比如有一个对象，我们希望在其中添加一个新的属性和值，但是我们在不确定它原来内部有什么内容的情况下
// 很容易造成冲突，从而覆盖掉它内部的某个属性

//ES6中Symbol的使用
// Symbol值是通过Symbol函数生成的，生成后可以作为属性名
// 也就是在ES6中，对象的属性名可以使用字符串，也可以使用Symbol值


const s1 = Symbol()
const s2 = Symbol()

// console.log(s1 === s2)

// ES2019(ES10)中，Symbol还有一个描述（description）
const s3 = Symbol("aaa")
// console.log(s3.description)

// 3 1.在定义字面量时使用
const obj={
    [s1]:"abc",
    [s2]:"cba"
}
// 3.2新增属性
obj[s3] = "nba"
// 3.3Object.defineProperty方式
const s4 = Symbol()
Object.defineProperty(obj,s4,{
    enumerable:true,
    configurable:true,
    writable:true,
    value:"mba"
})

console.log(obj[s1],obj[s2],obj[s3],obj[s4])

// 注意不能通过.语法获取
// console.log(obj.s1)

// 4.使用Symbol作为key的属性名，在遍历Object.keys等中获取不到这些Symbol值
console.log(Object.keys(obj))
console.log(Object.getOwnPropertyNames(obj))
console.log(Object.getOwnPropertySymbols(obj))
const sKeys = Object.getOwnPropertySymbols(obj)
for(const sKey of sKeys){
    console.log(obj[sKey])
}
